﻿

namespace Mulala.Cavan.Application.MainBoundedContext.NannyModule
{
    using System;
    using System.Collections.Generic;
    using Mulala.Cavan.Application.MainBoundedContext.ConsignModule;
    using Mulala.Cavan.Application.MainBoundedContext.CorporationModule;
    using Mulala.Cavan.Application.MainBoundedContext.LogModule;
    using Mulala.Cavan.Application.MainBoundedContext.MulalaModule;
    using Mulala.Cavan.Application.MainBoundedContext.ProprietorModule;
    using Mulala.Cavan.Application.MainBoundedContext.SecurityModule;
    using Mulala.Cavan.Core.Helper;
    using Mulala.Cavan.Domain.MainBoundedContext.ConsignModule;
    using Mulala.Cavan.Domain.MainBoundedContext.CorporationModule;
    using Mulala.Cavan.Domain.MainBoundedContext.DictionaryModule;
    using Mulala.Cavan.Domain.MainBoundedContext.LogModule;
    using Mulala.Cavan.Domain.MainBoundedContext.MulalaModule;
    using Mulala.Cavan.Domain.MainBoundedContext.NannyModule;
    using Mulala.Cavan.Domain.MainBoundedContext.ProprietorModule;
    using Mulala.Cavan.Domain.MainBoundedContext.SearchModule;
    using Mulala.Cavan.Domain.Seedwork;
    using Mulala.Cavan.Application.Seedwork;
    using Spring.Context;
    using Spring.Context.Support;
    using Mulala.Cavan.Domain.MainBoundedContext.AttachmentModule;
    using Mulala.Cavan.Application.MainBoundedContext.AttachmentModule;
    using System.Linq;
    using Mulala.Cavan.Domain.MainBoundedContext.SecurityModule;

    public class NannyAppService : BaseAppService<Nanny, NannySearch, INannyRepository>, INannyAppService
    {
        private IApplicationContext SpringContext = null;
        private INannyStatusRepository NannyStatusRepository { get; set; }
        private ICorporationAppService CorporationAppService { get; set; }
        private IConsignAppService ConsignAppService { get; set; }
        private ITagAppService TagAppService { get; set; }
        private IProprietorAppService ProprietorAppService { get; set; }
        private IVisitHistoryAppService VisitHistoryAppService { get; set; }
        private IAttachmentAppService AttachmentAppService { get; set; }
        private IRoleAppService RoleAppService { get; set; }
        private IAreaAppService AreaAppService { get; set; }

        public NannyAppService()
        {
        }

        #region INannyAppService Members
        public Nanny GetNannyById(int id)
        {
            Nanny nanny = base.GetById(id);
            nanny.ViewTotal = nanny.ViewTotal + 1;
            this.Repository.Update(nanny);
            this.LogVisitHistory(nanny);

            return nanny;
        }

        public override BoolGenericResult<Nanny> Update(Nanny changedNanny)
        {
            this.SpringContext = ContextRegistry.GetContext();
            this.AreaAppService = this.SpringContext.GetObject(MulalaAppServiceConst.AREAAPPSERVICE) as IAreaAppService;

            BoolGenericResult<Nanny> result = new BoolGenericResult<Nanny>();

            Nanny currentNanny = this.Repository.Get(changedNanny.ID);
            changedNanny.Area = this.AreaAppService.GetById(changedNanny.Area.ID);

            result = currentNanny.ModifyInof(changedNanny.Name, changedNanny.Age, changedNanny.Sex, changedNanny.Nation, changedNanny.Birthday, changedNanny.Telephone,
                                    changedNanny.Mobile, changedNanny.QQ, changedNanny.MSN, changedNanny.IsContactCompany, changedNanny.Astrology, changedNanny.ComputerLevel,
                                    changedNanny.ChineseZodiac, changedNanny.IsMarried, changedNanny.Language, changedNanny.Area, changedNanny.Address, changedNanny.Degree,
                                    changedNanny.CanDrive, changedNanny.HasChildren, changedNanny.Healthy, changedNanny.Faith, changedNanny.MainSkill, changedNanny.FirstSkill,
                                    changedNanny.SecondSkill, changedNanny.ThirdSkill, changedNanny.IsTrained, changedNanny.Experience, changedNanny.Salary, changedNanny.Introduce,
                                    changedNanny.Certificate, changedNanny.Declaration, changedNanny.Type, changedNanny.IsWorking, changedNanny.IsNeedAccommodate, changedNanny.IsNeedMeal);

            if (result.IsSuccess)
            {
                this.Repository.Update(currentNanny);
            }
            result.Messages.Add("保存成功");
            return result;
        }

        public BoolGenericResult<Attachment> UpdateNannyAvatar(Nanny changedNanny, string fileUrl, string fileName)
        {
            this.SpringContext = ContextRegistry.GetContext();
            this.AttachmentAppService = this.SpringContext.GetObject(MulalaAppServiceConst.ATTACHMENTAPPSERVICE) as IAttachmentAppService;

            BoolGenericResult<Attachment> result = new BoolGenericResult<Attachment>();
            Attachment avatar = changedNanny.Attachments.FirstOrDefault(a => a.AttachmentGroup == AttachmentIdentifier.AttachmentGroup.NannyAvatar);

            if (null == avatar)
            {
                avatar = AttachmentFactory.CreateAttachment(AttachmentIdentifier.AttachmentGroup.NannyAvatar, changedNanny.ID, fileName, fileUrl, true, AttachmentIdentifier.CheckedStatus.UnChecked,
                    false, 1, DateTime.Now, changedNanny.UserAccount.Name);
                this.AttachmentAppService.Add(avatar);
              
                result.Object = avatar;
            }
            else
            {
                result = changedNanny.ModifyAvatar(fileUrl, fileName);
                if (result.IsSuccess)
                {
                    this.AttachmentAppService.Update(result.Object);
                }
            }
            result.Messages.Add("保存成功！");
            return result;
        }

        public override BoolGenericResult<Nanny> Delete(Nanny deletedNanny)
        {
            this.SpringContext = ContextRegistry.GetContext();
            this.CorporationAppService = this.SpringContext.GetObject(MulalaAppServiceConst.CORPORATIONAPPSERVICE) as ICorporationAppService;
            this.ConsignAppService = this.SpringContext.GetObject(MulalaAppServiceConst.CONSIGNAPPSERVICE) as IConsignAppService;

            BoolGenericResult<Nanny> result = new BoolGenericResult<Nanny>();
            DeleteNannyResult deleteNannyResult = null;
            Nanny currentNanny = this.Repository.Get(deletedNanny.ID);
            deleteNannyResult = currentNanny.Corporation.DeleteNanny(currentNanny);

            if (result.IsSuccess)
            {
                this.Repository.Update(currentNanny);
                foreach (ConsignBidder cb in deleteNannyResult.DeletedConsignBidders)
                {
                    this.ConsignAppService.UpdateConsignBidder(cb);
                }
            }

            result.Object = deleteNannyResult.Object;

            return result;
        }

        public BoolGenericResult<NannyStatus> UpdateNannyVipStatus(Nanny changedNanny, bool isVip, int vipValidMonth = 0)
        {
            this.SpringContext = ContextRegistry.GetContext();
            this.CorporationAppService = this.SpringContext.GetObject(MulalaAppServiceConst.CORPORATIONAPPSERVICE) as ICorporationAppService;

            BoolGenericResult<NannyStatus> result = new BoolGenericResult<NannyStatus>();
            Nanny currentNanny = this.Repository.Get(changedNanny.ID);
            if (isVip)
            {
                result = currentNanny.Corporation.SetNannyToVip(currentNanny, vipValidMonth);
            }
            else
            {
                result = currentNanny.Corporation.SetNannyToUnVip(currentNanny);
            }

            if (result.IsSuccess)
            {
                this.Repository.Update(currentNanny);
                this.CorporationAppService.UpdateCorporationStatus(currentNanny.Corporation.CorporationStatus);
            }

            return result;
        }

        public BoolGenericResult<NannyStatus> UpdateNannyOnlineStatus(Nanny changedNanny, bool isOnLine)
        {
            this.SpringContext = ContextRegistry.GetContext();
            this.CorporationAppService = this.SpringContext.GetObject(MulalaAppServiceConst.CORPORATIONAPPSERVICE) as ICorporationAppService;

            BoolGenericResult<NannyStatus> result = new BoolGenericResult<NannyStatus>();
            Nanny currentNanny = this.Repository.Get(changedNanny.ID);
            if (isOnLine)
            {
                result = currentNanny.Corporation.SetNannyToOnline(currentNanny);
            }
            else
            {
                result = currentNanny.Corporation.SetNannyToOffline(currentNanny);
            }

            if (result.IsSuccess)
            {
                this.Repository.Update(currentNanny);
            }

            return result;
        }

        public BoolGenericResult<NannyStatus> UpdateNannyBidStatus(Nanny changedNanny, bool canBid)
        {
            this.SpringContext = ContextRegistry.GetContext();
            this.CorporationAppService = this.SpringContext.GetObject(MulalaAppServiceConst.CORPORATIONAPPSERVICE) as ICorporationAppService;

            BoolGenericResult<NannyStatus> result = new BoolGenericResult<NannyStatus>();
            Nanny currentNanny = this.Repository.Get(changedNanny.ID);
            Corporation corporation = currentNanny.Corporation;
            if (canBid)
            {
                result = corporation.SetNannyToCanBid(currentNanny);
            }
            else
            {
                result = corporation.SetNannyToCannotBid(currentNanny);
            }

            if (result.IsSuccess)
            {
                this.Repository.Update(currentNanny);
            }

            return result;
        }

        public BoolGenericResult<NannyStatus> UpdateNannyRecommendStatus(Nanny changedNanny, bool isRecommend, int recommendValidMonth = 0)
        {
            this.SpringContext = ContextRegistry.GetContext();
            this.CorporationAppService = this.SpringContext.GetObject(MulalaAppServiceConst.CORPORATIONAPPSERVICE) as ICorporationAppService;

            BoolGenericResult<NannyStatus> result = new BoolGenericResult<NannyStatus>();
            Nanny currentNanny = this.Repository.Get(changedNanny.ID);
            if (isRecommend)
            {
                result = currentNanny.Corporation.SetNannyToRecommend(currentNanny, recommendValidMonth);
            }
            else
            {
                result = currentNanny.Corporation.SetNannyToUnRecommend(currentNanny);
            }

            if (result.IsSuccess)
            {
                this.Update(currentNanny);
                this.CorporationAppService.UpdateCorporationStatus(currentNanny.Corporation.CorporationStatus);
            }

            return result;
        }

        public BoolGenericResult<NannyStatus> UpdateNannyRefreshTime(Nanny changedNanny)
        {
            BoolGenericResult<NannyStatus> result = new BoolGenericResult<NannyStatus>();
            Nanny nanny = this.Repository.Get(changedNanny.ID);
            result = nanny.RefreshSelf();

            if (result.IsSuccess)
            {
                this.NannyStatusRepository.Update(result.Object);
            }

            return result;
        }

        public BoolGenericResult<Nanny> UpdateNannyWorkingStatus(Nanny changedNanny, bool isWorking)
        {
            BoolGenericResult<Nanny> result = new BoolGenericResult<Nanny>();
            Nanny nanny = this.Repository.Get(changedNanny.ID);
            result = nanny.DoWork(isWorking);

            if (result.IsSuccess)
            {
                this.Repository.Update(nanny);
            }
            result.Messages.Add("执行成功");
            return result;
        }

        public IList<Nanny> GetNanniesByKeyword(string keyword, int currentPage, out long total)
        {
            NannySearch nannySearch = ParseKeywordToNannySearch(keyword);
            nannySearch.CurrentPage = currentPage;

            IList<Nanny> nannies = this.GetBySearch(nannySearch, out total).ToList();

            return nannies;
        }

        private NannySearch ParseKeywordToNannySearch(string keywork)
        {
            this.SpringContext = ContextRegistry.GetContext();
            this.TagAppService = this.SpringContext.GetObject(MulalaAppServiceConst.TAGAPPSERVICE) as ITagAppService;
            NannySearch nannySearch = new NannySearch();
            string[] keywords = StringHelper.ClearExtraSpace(keywork).Split(' ');
            List<int> skillPositions = new List<int>();
            foreach (string kw in keywords)
            {
                TagSearch tagSearch = TagSearchFactory.CreateTagSearch(kw);
                Tag tag = this.TagAppService.GetSingleBySearch(tagSearch);
                if (null != tag)
                {
                    if (tag.TagGroup.ID == DictionaryIdentifier.GroupType.NannyType.GetHashCode())
                    {
                        nannySearch.Type = (NannyIdentifier.NannyType)int.Parse(tag.Value);
                    }
                    else if (tag.TagGroup.ID == DictionaryIdentifier.GroupType.NannySkill.GetHashCode())
                    {
                        skillPositions.Add(tag.BinaryPosition);
                    }
                }
            }
            if (skillPositions.Count > 0)
            {
                nannySearch.SkillPosition = skillPositions.ToArray();
            }
            return nannySearch;
        }

        private void LogVisitHistory(Nanny nanny)
        {
            this.SpringContext = ContextRegistry.GetContext();
            this.VisitHistoryAppService = this.SpringContext.GetObject(MulalaAppServiceConst.VISITHISTORYAPPSERVICE) as IVisitHistoryAppService;

            if (SecurityAppService.IsLogon)
            {
                VisitHistorySearch visitHistorySearch = new VisitHistorySearch();
                visitHistorySearch.IntervieweeID = nanny.ID;
                visitHistorySearch.VisitorID = SecurityAppService.UserAccount.ID;
                VisitHistory visitHistory = this.VisitHistoryAppService.GetSingleBySearch(visitHistorySearch);
                if (null == visitHistory)
                {
                    this.VisitHistoryAppService.AddVisitHistory(nanny.UserAccount, CavanWebUtility.GetUserIP(), SecurityAppService.UserAccount);
                }
                else
                {
                    visitHistory.LastVisitTime = DateTime.Now;
                    this.VisitHistoryAppService.Update(visitHistory);
                }
            }
        }

        public BoolGenericResult<Nanny> AddNannyByCorporation(Nanny addedNanny)
        {
            this.SpringContext = ContextRegistry.GetContext();
            this.RoleAppService = this.SpringContext.GetObject(MulalaAppServiceConst.ROLEAPPSERVICE) as IRoleAppService;
            this.CorporationAppService = this.SpringContext.GetObject(MulalaAppServiceConst.CORPORATIONAPPSERVICE) as ICorporationAppService;

            Corporation corporation = this.CorporationAppService.GetById(addedNanny.Corporation.ID);

            Role role = this.RoleAppService.GetById(SecurityIdentifier.Role.Nanny.GetHashCode());
            addedNanny.UserAccount.Roles = new List<Role>();
            addedNanny.UserAccount.Roles.Add(role);
            UserAccount newUserAccount = UserAccountFactory.CreateUserAccount(addedNanny.UserAccount.Name, addedNanny.UserAccount.Password, addedNanny.UserAccount.Email, addedNanny.UserAccount.Roles);

            BoolGenericResult<Nanny> result = corporation.AddNanny(newUserAccount, addedNanny.Name, addedNanny.Age, addedNanny.Sex, addedNanny.Nation,
                addedNanny.Birthday, addedNanny.Telephone, addedNanny.Mobile, addedNanny.QQ, addedNanny.MSN, addedNanny.IsContactCompany, addedNanny.Astrology,
                addedNanny.ComputerLevel, addedNanny.ChineseZodiac, addedNanny.IsMarried, addedNanny.Language, addedNanny.Area, addedNanny.Address, addedNanny.Degree,
                addedNanny.CanDrive, addedNanny.HasChildren, addedNanny.Healthy, addedNanny.Faith, addedNanny.MainSkill, addedNanny.FirstSkill, addedNanny.SecondSkill, 
                addedNanny.ThirdSkill, addedNanny.IsTrained, addedNanny.Experience, addedNanny.Salary, addedNanny.Introduce, addedNanny.Certificate, addedNanny.Declaration, 
                addedNanny.Type, addedNanny.IsWorking, addedNanny.IsNeedAccommodate, addedNanny.IsNeedMeal);

            if (result.IsSuccess)
            {
                this.Repository.Save(result.Object);
            }

            return result;
        }

        public BoolGenericResult<Attachment> UpdateNannyPhoto(Nanny changedNanny, int photoID, string fileUrl, string fileName)
        {
            this.SpringContext = ContextRegistry.GetContext();
            this.AttachmentAppService = this.SpringContext.GetObject(MulalaAppServiceConst.ATTACHMENTAPPSERVICE) as IAttachmentAppService;

            BoolGenericResult<Attachment> result = new BoolGenericResult<Attachment>();
            Attachment photo = changedNanny.Attachments.FirstOrDefault(a => a.ID == photoID && a.AttachmentGroup == AttachmentIdentifier.AttachmentGroup.NannyPhoto);

            if (null == photo)
            {
                result = changedNanny.UploadPhoto(fileUrl, fileName);

                this.AttachmentAppService.Add(result.Object);
            }
            else
            {
                result = changedNanny.ModifyPhoto(photoID, fileUrl, fileName);
                if (result.IsSuccess)
                {
                    this.AttachmentAppService.Update(result.Object);
                }
            }
            result.Messages.Add("保存成功！");
            return result;
        }

        #endregion
    }
}
